package state;

import java.util.Vector;

import state.font.FontManager;
import state.font.ImageText;
import state.util.Color;
import state.util.ImageUtil;

public class Alert extends GameForm implements TimerListener, TouchScreenListener {
	/** Kiểu Alert với 1 nút OK */
	public static final byte OK_TYPE = 0;

	/** Kiểu Alert với 2 nút Yes và No */
	public static final byte YES_NO_TYPE = 1;

	/** Alert kiểu loading form */
	public static final byte LOADING_FORM = 2;

	/** Alert kiểu loading và có nút cancel để dừng xử lý loading */
	public static final byte LOADING_WITH_CANCEL_BUTTON_TYPE = 3;

	/** Alert kiểu có danh sách các nút do người dùng quyết định */
	private final byte CUSTOM_BUTTON_TYPE = 4;

	/** Alert kiểu cho phép người dùng input number */
	public static final byte INPUT_NUMBER_TYPE = 5;
	
	/** Alert kiểu cho phép người dùng config table */
	public static final byte CUSTOM_UI_TYPE = 6;
	
	/** Alert kiểu loading và không có button */
	public static final byte LOADING_WITH_NO_BUTTON_TYPE = 7;

	/** Sắp xếp ngang */
	public static final byte HORIZONTAL_ALINE = 0;

	/** Sắp xếp dọc */
	public static final byte VERTICAL_ALINE = 1;

	public static final byte BUTTON_WIDTH_SMALL = 0;
	public static final byte BUTTON_WIDTH_LARGE = 1;

	public static final byte ALERT_ID_NOT_DEFINE = -1;
	public static final byte OK_BUTTON = 0;
	public static final byte YES_BUTTON = 1;
	public static final byte NO_BUTTON = 2;
	public static final byte LOADING_DONE_EVENT = 3;
	public static final byte CANCEL_BUTTON = 4;

	private final byte MAX_NUMBER_LEN = 5;
	private final byte BUTTON_DISTANCE_HORIZONTAL = 15;
	private final byte BUTTON_DISTANCE_VERTICAL = 5;
	
	private Sprite[] buttonSprites;

	private Image bgImage;
	private Image buttonImage;
	private Image focusedButtonImage;
	private Image coverImage;
	private Image loadingImage1;
	private Image loadingImage2;
	private Image bgLoadingImage;
	private Image buttonSmallImage;
  private Image buttonSmallFocusImage;
  private Image buttonLargeImage;
  private Image buttonLargeFocusImage;

	private int alertType;
	private Vector alertMessages;
	private int alertId;
	private GameForm parent;
	private String[] buttonLabels;
	private int alineType;

	private int buttonIndex;
	private int alertX;
	private int alertY;
	private int messageY;
	private ImageText vnText;
	private int buttonWidth;
	private boolean isAutoHideInEvent;
	private int count;
	private AlertListener listenner;
	private GameForm customeUI;
	private int alertTimeOut = Integer.MAX_VALUE;
	
	private static Alert instance;

	protected Alert() {
		alertMessages = new Vector();
	}
	
	public GameForm create() {
	  return new Alert();
	}
	
	public static GameForm instance() {
	  if (instance == null) {
	    instance = new Alert();
	  }
		return instance;
	}

	public Alert setListenner(AlertListener listenner) {
		this.listenner = listenner;
		return this;
	}
	
	/**
   * Hiển thị Alert OK
   * 
   * @param alertMessage - chuỗi thông báo, bằng null hoặc empty nếu không có message
   */
	public Alert alert(String alertMessage) {
	  return showAlert(null, Alert.OK_TYPE, alertMessage);
	}
	
	 /**
   * Hiển thị Alert OK
   * 
   * @param alertMessage - chuỗi thông báo, bằng null hoặc empty nếu không có message
   */
  public Alert alert(String[] alertMessage) {
    return showAlert(null, Alert.OK_TYPE, alertMessage);
  }


	/**
	 * Hiển thị Alert
	 * 
	 * @param parent - State hiển thị nền
	 * @param listenner - Listener để handle sự kiện Alert, bằng null nếu sự kiện trả về cho parent
	 * @param alertType - Kiểu Alert
	 * @param alertMessage - chuỗi thông báo, bằng null hoặc empty nếu không có message
	 */
	public Alert showAlert(AlertListener listenner, byte alertType, String alertMessage) {
		return showAlert(listenner, alertType, alertMessage, 0);
	}

	/**
	 * Hiển thị Alert
	 * 
	 * @param parent - State hiển thị nền
	 * @param listenner - Listener để handle sự kiện Alert, bằng null nếu sự kiện trả về cho parent
	 * @param alertType - Kiểu Alert
	 * @param alertMessage - chuỗi thông báo, bằng null hoặc empty nếu không có message
	 * @param alertId - Id cho lần gọi alert này, dùng để nhận biết cho hàm alertEventPerform trả về cho State. Giá trị của alertId do người dùng thiết lập.
	 */
	public Alert showAlert(AlertListener listenner, byte alertType, String alertMessage, int alertId) {
		return showAlert(listenner, alertType, new String[]{alertMessage}, alertId);
	}

	/**
	 * Hiển thị Alert
	 * 
	 * @param parent - State hiển thị nền
	 * @param listenner - Listener để handle sự kiện Alert, bằng null nếu sự kiện trả về cho parent
	 * @param alertType - Kiểu Alert
	 * @param alertMessages - mảng chuỗi thông báo, bằng null hoặc empty nếu không có message nào
	 */
	public Alert showAlert(AlertListener listenner, byte alertType, String[] alertMessages) {
		return showAlert(listenner, alertType, alertMessages, 0);
	}

	/**
	 * Hiển thị Alert
	 * 
	 * @param parent - State hiển thị nền
	 * @param listenner - Listener để handle sự kiện Alert, bằng null nếu sự kiện trả về cho parent
	 * @param alertType - Kiểu Alert
	 * @param alertMessages - mảng chuỗi thông báo, bằng null hoặc empty nếu không có message nào
	 * @param alertId - Id cho lần gọi alert này, dùng để nhận biết cho hàm alertEventPerform trả về cho State. Giá trị của alertId do người dùng thiết lập.
	 */
	public Alert showAlert(AlertListener listenner, byte alertType, String[] alertMessages, int alertId) {
		this.alertType = alertType;
		this.parent = findParent();

		if (listenner == null) {
			this.listenner = parent;
		} else {
			this.listenner = listenner;
		}

		this.alertId = alertId;
		this.alertMessages.removeAllElements();
		if (alertMessages != null) {
			for (int i = 0; i < alertMessages.length; i++) {
				this.alertMessages.addElement(alertMessages[i]);
			}
		}
		return showAlert();
	}

	/**
	 * Hiển thị Alert với danh sách các nút do người dùng quyết định
	 * 
	 * @param parent - State hiển thị nền
	 * @param listenner - Listener để handle sự kiện Alert, bằng null nếu sự kiện trả về cho parent
	 * @param buttonLabels - Danh sách các nút cần hiển thị
	 * @param buttonWidth - Kiểu chiều rộng của mỗi button
	 * @param alertMessages - Mảng chuỗi thông báo, bằng null hoặc empty nếu không có message nào
	 * @param alertId - Id cho lần gọi alert này, dùng để nhận biết cho hàm alertEventPerform trả về cho State. Giá trị của alertId do người dùng thiết lập.
	 * @param alineType - Kiểu sắp xếp ngang hay dọc (HORIZONTAL_ALINE hoặc VERTICAL_ALINE)
	 */
	public Alert showCustomButtonAlert(AlertListener listenner, String[] buttonLabels, byte buttonWidth, String[] alertMessages, int alertId, byte alineType) {
		this.alertType = CUSTOM_BUTTON_TYPE;
		this.parent = findParent();

		if (listenner == null) {
			this.listenner = parent;
		} else {
			this.listenner = listenner;
		}

		this.alertMessages.removeAllElements();
		if (alertMessages != null) {
			for (int i = 0; i < alertMessages.length; i++) {
				this.alertMessages.addElement(alertMessages[i]);
			}
		}
		this.alertId = alertId;
		this.buttonLabels = buttonLabels;
		this.alineType = alineType;
		this.buttonWidth = buttonWidth;
		return showAlert();
	}

	/**
	 * Hiển thị Alert với danh sách các nút do người dùng quyết định
	 * 
	 * @param parent - State hiển thị nền
	 * @param listenner - Listener để handle sự kiện Alert, bằng null nếu sự kiện trả về cho parent
	 * @param buttonLabels - Danh sách các nút cần hiển thị
	 * @param buttonWidth - Kiểu chiều rộng của mỗi button
	 * @param alertMessage - Chuỗi thông báo, bằng null hoặc empty nếu không có message
	 * @param alertId - Id cho lần gọi alert này, dùng để nhận biết cho hàm alertEventPerform trả về cho State. Giá trị của alertId do người dùng thiết lập.
	 * @param alineType - Kiểu sắp xếp ngang hay dọc (HORIZONTAL_ALINE hoặc VERTICAL_ALINE)
	 */
	public Alert showCustomButtonAlert(AlertListener listenner, String[] buttonLabels, byte buttonWidth, String alertMessage, int alertId, byte alineType) {
		this.alertType = CUSTOM_BUTTON_TYPE;
		this.parent = findParent();

		if (listenner == null) {
			this.listenner = parent;
		} else {
			this.listenner = listenner;
		}

		this.alertMessages.removeAllElements();
		if (alertMessage != null) {
			this.alertMessages.addElement(alertMessage);
		}
		this.alertId = alertId;
		this.buttonLabels = buttonLabels;
		this.alineType = alineType;
		this.buttonWidth = buttonWidth;
		return showAlert();
	}
	
	public Alert showCustomUIAlert(GameForm customeUI, int alertId) {
		this.alertType = CUSTOM_UI_TYPE;
		this.customeUI = customeUI;
		customeUI.isRunning = true;
		customeUI.init(null);
		
		this.parent = findParent();

		this.alertId = alertId;
		return showAlert();
	}
	
	private GameForm findParent() {
		GameForm parent = GameGlobal.systemCanvas.frmCurrent;
		if (parent == this) {
			return this.parent;
		}
		return parent;
	}
	
	public boolean isShowing() {
		return GameGlobal.systemCanvas.frmCurrent == this;
	}
	
	public int getAlertType() {
		return alertType;
	}
	
	public int getAlertId() {
		return alertId;
	}

	private Alert showAlert() {
	  if (alertType != CUSTOM_UI_TYPE) {
	    setSize(GameConstants.SCREEN_WIDTH, GameConstants.SCREEN_HEIGHT);
	    buttonIndex = 0;
	    count = 0;
	    if (alertType == INPUT_NUMBER_TYPE) {
	      alertMessages.addElement("");
	      alertMessages.addElement("");
	    }

	    messageY = 35;
	    switch (alertType) {
	    case OK_TYPE:
	      buttonWidth = BUTTON_WIDTH_SMALL;
	      buttonLabels = new String[]{"Đồng ý"};
	      break;
	    case YES_NO_TYPE:
	      buttonWidth = BUTTON_WIDTH_SMALL;
	      buttonLabels = new String[]{"Đồng ý", "Hủy"};
	      break;
	    case LOADING_FORM:
	      buttonLabels = new String[0];
	      break;
	    case LOADING_WITH_CANCEL_BUTTON_TYPE:
	      buttonWidth = BUTTON_WIDTH_SMALL;
	      buttonLabels = new String[]{"Dừng"};
	      break;
	    case CUSTOM_BUTTON_TYPE:
	      if (alineType == VERTICAL_ALINE) {
	        messageY = 11;
	      }
	      break;
	    case INPUT_NUMBER_TYPE:
	      alertId = 0;
	      buttonLabels = new String[]{"Đồng ý"};
	      break;
	    }
	    
	    loadImage();
	    alertX = (GameConstants.SCREEN_WIDTH - bgImage.getWidth()) / 2;
	    alertY = (GameConstants.SCREEN_HEIGHT - bgImage.getHeight()) / 2;
	    vnText = FontManager.getFont(FontManager.FONT_SIZE_8);
	    
	    switch (alertType) {
	    case OK_TYPE:
	    case YES_NO_TYPE:
	    case LOADING_WITH_CANCEL_BUTTON_TYPE:
	    case INPUT_NUMBER_TYPE:
	      createHorizontalButtons();
	      break;
	    case CUSTOM_BUTTON_TYPE:
	      if (alineType == HORIZONTAL_ALINE) {
	        createHorizontalButtons();
	      } else if (alineType == VERTICAL_ALINE) {
	        createVerticalButtons();
	      }
	      break;
	    }
	  }

		setTimerListener(this);
		isRunning = true;
		GameGlobal.systemCanvas.changeHandleToAlert();
		return this;
	}
	
	private void loadImage() {
		bgImage = (bgImage == null) ? ImageUtil.getCoreImage("bg_popup.png").setStatic(true) : bgImage;
		if (coverImage == null) {
		  coverImage = ImageUtil.getCoreImage("pxiel_nen.png");
	    coverImage = ImageUtil.joinAndCreateImages(coverImage, GameConstants.SCREEN_WIDTH, GameConstants.SCREEN_HEIGHT, true).setStatic(true);
		}
		
		if (buttonWidth == BUTTON_WIDTH_SMALL) {
			buttonImage = (buttonSmallImage == null) ? buttonSmallImage = ImageUtil.getCoreImage("button_nho.png").setStatic(true) : buttonSmallImage;
			focusedButtonImage = (buttonSmallFocusImage == null) ? buttonSmallFocusImage = ImageUtil.getCoreImage("button_nho_focus.png").setStatic(true) : buttonSmallFocusImage;
		} else {
		  buttonImage = (buttonLargeImage == null) ? buttonLargeImage = ImageUtil.getCoreImage("button_to.png").setStatic(true) : buttonLargeImage;
		  focusedButtonImage = (buttonLargeFocusImage == null) ? buttonLargeFocusImage = ImageUtil.getCoreImage("button_to_focus.png").setStatic(true) : buttonLargeFocusImage;
		}
		
		if ((alertType == LOADING_FORM) || (alertType == LOADING_WITH_CANCEL_BUTTON_TYPE)) {
			loadingImage1 = (loadingImage1 == null) ? ImageUtil.getCoreImage("loading_1.png").setStatic(true) : loadingImage1;
			loadingImage2 = (loadingImage2 == null) ? ImageUtil.getCoreImage("loading_2.png").setStatic(true) : loadingImage2;
		} else if (alertType == LOADING_WITH_NO_BUTTON_TYPE) {
			loadingImage1 = (loadingImage1 == null) ? ImageUtil.getCoreImage("loading_1.png").setStatic(true) : loadingImage1;
			loadingImage2 = (loadingImage2 == null) ? ImageUtil.getCoreImage("loading_2.png").setStatic(true) : loadingImage2;
			bgLoadingImage = (bgLoadingImage == null) ? ImageUtil.getCoreImage("bg_loading.png").setStatic(true) : bgLoadingImage;
		}
	}

	/**
	 * Lấy State hiển thị nền của Alert
	 * 
	 * @return State là parent của Alert
	 */
	public GameForm getParent() {
		return parent;
	}

	public void doTask() {
		count++;
		if (alertType == LOADING_WITH_NO_BUTTON_TYPE && count >= alertTimeOut) {
			GameGlobal.systemCanvas.hideAlert();
			listenner.alertEventPerform(alertType, 0, alertId); // Khi timeout thì báo lại sự kiện ra ngoài
		}
	}
	
	public void draw(Graphics g) {
	  if (alertType != CUSTOM_UI_TYPE) {
	    g.setClip(0, 0, GameConstants.SCREEN_WIDTH, GameConstants.SCREEN_HEIGHT);
	  }
	  
		// Vẽ nền
		if ((alertType == LOADING_FORM) || (alertType == LOADING_WITH_CANCEL_BUTTON_TYPE)) {
			g.setColor(0x4F0202);
			g.fillRect(0, 0, GameConstants.SCREEN_WIDTH, GameConstants.SCREEN_HEIGHT);
		} else if (alertType == LOADING_WITH_NO_BUTTON_TYPE) {
			parent.updateFullScreen();
			g.drawImage(coverImage, 0, 0, GameConstants.TOP_LEFT_ANCHOR);
		} else if (alertType == CUSTOM_UI_TYPE) { 
      parent.updateFullScreen();
		} else {
			parent.updateFullScreen();
			g.drawImage(coverImage, 0, 0, GameConstants.TOP_LEFT_ANCHOR);
			g.drawImage(bgImage, alertX, alertY, GameConstants.TOP_LEFT_ANCHOR);
		}
		
		if (alertType != CUSTOM_UI_TYPE) { 
		  // Viết message
	    if ((alertType != LOADING_FORM) && (alertType != LOADING_WITH_CANCEL_BUTTON_TYPE) && (alertType != LOADING_WITH_NO_BUTTON_TYPE)) {
	      for (int i = 0; i < alertMessages.size(); i++) {
	        vnText.drawString(g, String.valueOf(alertMessages.elementAt(i)), Color.WHITE_CODE, GameConstants.SCREEN_WIDTH / 2, alertY + messageY + 16 * i, GameConstants.TOP_HCENTER_ANCHOR);
	      }
	    }
		}
		
		// Draw loading bar
		if ((alertType == LOADING_FORM) || (alertType == LOADING_WITH_CANCEL_BUTTON_TYPE)) {
			int index = count % 11;
			int x = 0;
			int y = 0;
			if (GameConstants.IS_240x320_SCREEN) {
				vnText.drawString(g, "Đang tải...", Color.WHITE_CODE, GameConstants.SCREEN_WIDTH / 2, 264, GameConstants.TOP_HCENTER_ANCHOR);
				x = 62;
				y = 247;
			} else {
				vnText.drawString(g, "Đang tải...", Color.WHITE_CODE, GameConstants.SCREEN_WIDTH / 2, 193, GameConstants.TOP_HCENTER_ANCHOR);
				x = 101;
				y = 172;
			}
			
			for (int i = 1; i < 11; i++) {
				if (i <= index) {
					g.drawImage(loadingImage1, x + (loadingImage1.getWidth() + 1) * (i - 1), y, GameConstants.TOP_LEFT_ANCHOR);
				} else {
					g.drawImage(loadingImage2, x + (loadingImage1.getWidth() + 1) * (i - 1), y, GameConstants.TOP_LEFT_ANCHOR);
				}
			}
		} else if (alertType == LOADING_WITH_NO_BUTTON_TYPE) {
			int x = 0;
			int index = count % 11;
			g.drawImage(bgLoadingImage, GameConstants.SCREEN_WIDTH / 2, GameConstants.SCREEN_HEIGHT / 2 - 2, GameConstants.CENTER_ANCHOR);
			if (GameConstants.IS_240x320_SCREEN) {
				if (alertMessages.size() > 0) {
					vnText.drawString(g,  String.valueOf(alertMessages.elementAt(0)), Color.WHITE_CODE, GameConstants.SCREEN_WIDTH / 2, GameConstants.SCREEN_HEIGHT / 2 + 3, GameConstants.TOP_HCENTER_ANCHOR);
				}
				x = 62;
			} else {
				if (alertMessages.size() > 0) {
					vnText.drawString(g, String.valueOf(alertMessages.elementAt(0)), Color.WHITE_CODE, GameConstants.SCREEN_WIDTH / 2, GameConstants.SCREEN_HEIGHT / 2 + 3, GameConstants.TOP_HCENTER_ANCHOR);
				}
				x = 101;
			}
			for (int i = 1; i < 11; i++) {
				if (i <= index) {
					g.drawImage(loadingImage1, x + (loadingImage1.getWidth() + 1) * (i - 1), GameConstants.SCREEN_HEIGHT / 2 - 15, GameConstants.TOP_LEFT_ANCHOR);
				} else {
					g.drawImage(loadingImage2, x + (loadingImage1.getWidth() + 1) * (i - 1), GameConstants.SCREEN_HEIGHT / 2 - 15, GameConstants.TOP_LEFT_ANCHOR);
				}
			}
		} else if (alertType == INPUT_NUMBER_TYPE) { // Draw Input text field
			g.setColor(Color.WHITE_CODE);
			g.fillRect(GameConstants.SCREEN_WIDTH / 2 - 50, alertY + 15 + (alertMessages.size() - 2) * 20, 100, 18);
			vnText.drawString(g, String.valueOf(alertId), Color.BLUE_CODE, GameConstants.SCREEN_WIDTH / 2 - 48, alertY + 13 + (alertMessages.size() - 2) * 20, GameConstants.TOP_LEFT_ANCHOR);
			vnText.drawString(g, "Xóa", Color.WHITE_CODE, GameConstants.SCREEN_WIDTH - 10, alertY - 5 + alertMessages.size() * 20, GameConstants.TOP_RIGHT_ANCHOR);
		} else if (alertType == CUSTOM_UI_TYPE) {
		  if (customeUI != null) {
		    customeUI.updateFullScreen();
		  }
		}
	}
	
  private void createHorizontalButtons() {
    if (buttonLabels == null) {
      return;
    }
    int leftX = (GameConstants.SCREEN_WIDTH - buttonImage.getWidth() * buttonLabels.length - (buttonLabels.length - 1) * BUTTON_DISTANCE_HORIZONTAL) / 2;
    int x = leftX;

    buttonSprites = new Sprite[buttonLabels.length];
    for (int i = 0; i < buttonLabels.length; i++) {
      buttonSprites[i] = new Sprite(buttonImage, manager, x, alertY + 100);
      final int index = i;
      buttonSprites[i].setDrawListener(new DrawListener() {
        public void paint(Sprite source, Graphics g) {
          vnText.drawString(g, buttonLabels[index], Color.WHITE_CODE, source.getRealX() + buttonImage.getWidth() / 2, alertY + 100 + buttonImage.getHeight() / 2, GameConstants.CENTER_ANCHOR);
        }
      });
      buttonSprites[i].setTouchScreenListener(this);
      x += buttonImage.getWidth() + BUTTON_DISTANCE_HORIZONTAL;
    }
    updateFocus();
  }

	private void createVerticalButtons() {
	  if (buttonLabels == null) {
      return;
    }
		int topY = alertY + 65;
		int y = topY;
		buttonSprites = new Sprite[buttonLabels.length];
		for (int i = 0; i < buttonLabels.length; i++) {
		  buttonSprites[i] = new Sprite(buttonImage, manager, GameConstants.SCREEN_WIDTH / 2, y, GameConstants.TOP_HCENTER_ANCHOR);
		  final int index = i;
      buttonSprites[i].setDrawListener(new DrawListener() {
        public void paint(Sprite source, Graphics g) {
          vnText.drawString(g, buttonLabels[index], Color.WHITE_CODE, GameConstants.SCREEN_WIDTH / 2, source.getRealY() + buttonImage.getHeight() / 2, GameConstants.CENTER_ANCHOR);
        }
      });
      buttonSprites[i].setTouchScreenListener(this);
			y += buttonImage.getHeight() + BUTTON_DISTANCE_VERTICAL;
		}
		updateFocus();
	}
	
  public void pointerDragged(Sprite source, int x, int y) {
  }

  public void pointerPressed(Sprite source, int x, int y) {
  }

  public void pointerReleased(Sprite source, int x, int y) {
    if (buttonLabels == null) {
      return;
    }
    
    for (int i = 0; i < buttonSprites.length; i++) {
      if (source == buttonSprites[i]) {
        buttonIndex = i;
        break;
      }
    }
    updateFocus();
    executeEvent();
  }

	/**
	 * Thiết lập số % hiện tại của loading Alert, nếu đạt 100% thì loading Alert sẽ tự động callback lại hàm alertEventPerform của State
	 * 
	 * @param loadingPercent - Số % hiện tại
	 */
	public void setLoadingPercent(int loadingPercent) {
		if (loadingPercent >= 100) {
			if (parent != null) {
				parent.alertEventPerform(alertType, LOADING_DONE_EVENT, alertId);
			}
		}
	}

	public void setAutoHideInEvent(boolean isAutoHideInEvent) {
		this.isAutoHideInEvent = isAutoHideInEvent;
	}
	
	public int getAlertTimeOut() {
		return alertTimeOut;
	}

	public Alert setAlertTimeOut(int alertTimeOut) {
		this.alertTimeOut = alertTimeOut / GameGlobal.systemCanvas.getTimer().getDelay();
		return this;
	}
	
	private void updateFocus() {
	  if (buttonSprites != null) {
	    for (int i = 0; i < buttonSprites.length; i++) {
	      if (i == buttonIndex) {
	        buttonSprites[i].setImage(focusedButtonImage);
	      } else {
	        buttonSprites[i].setImage(buttonImage);
	      }
	    }
	  }
	}

	public void keyReleased(int keyCode) {
	  if (alertType == CUSTOM_UI_TYPE) {
      customeUI.doKeyReleased(keyCode);
      return;
    }
	  
		if ((buttonLabels == null) || (buttonLabels.length == 0)) {
			return;
		}
		
		switch (keyCode) {
		case Key.UP:
			buttonIndex--;
			if (buttonIndex < 0) {
				buttonIndex = (byte) (buttonLabels.length - 1);
			}
			updateFocus();
			break;
		case Key.DOWN:
			buttonIndex++;
			buttonIndex = (byte) (buttonIndex % buttonLabels.length);
			updateFocus();
			break;
		case Key.LEFT:
			buttonIndex--;
			if (buttonIndex < 0) {
				buttonIndex = (byte) (buttonLabels.length - 1);
			}
			updateFocus();
			break;
		case Key.RIGHT:
			buttonIndex++;
			buttonIndex = (byte) (buttonIndex % buttonLabels.length);
			updateFocus();
			break;
		case Key.FIRE:
		  executeEvent();
			break;
		case Key.SOFT_RIGHT:
			String str = String.valueOf(alertId);
			if (str.length() < 2) {
				alertId = 0;
			} else {
				alertId = Integer.parseInt(str.substring(0, str.length() - 1));
			}
			break;
		default:
			if (alertType == INPUT_NUMBER_TYPE) {
				if ((Key.K_0 <= keyCode) && (keyCode <= Key.K_9)) {
					int value = keyCode - Key.K_0;
					if (alertId == 0) {
						alertId = value;
					} else if (String.valueOf(alertId).length() < MAX_NUMBER_LEN) {
						alertId = Integer.parseInt(alertId + String.valueOf(value));
					}
				}
			}
			break;
		}
	}
	
	private void executeEvent() {
	  if (listenner == null) {
      GameGlobal.systemCanvas.hideAlert();
      return;
    }
    if (isAutoHideInEvent) {
      GameGlobal.systemCanvas.hideAlert();
    }
    switch (alertType) {
    case OK_TYPE:
      listenner.alertEventPerform(alertType, OK_BUTTON, alertId);
      break;
    case YES_NO_TYPE:
      switch (buttonIndex) {
      case 0:
        listenner.alertEventPerform(alertType, YES_BUTTON, alertId);
        break;
      case 1:
        listenner.alertEventPerform(alertType, NO_BUTTON, alertId);
        break;
      }
      break;
    case LOADING_WITH_CANCEL_BUTTON_TYPE:
      listenner.alertEventPerform(alertType, CANCEL_BUTTON, alertId);
      break;
    case CUSTOM_BUTTON_TYPE:
      listenner.alertEventPerform(alertType, buttonIndex, alertId);
      break;
    case INPUT_NUMBER_TYPE:
      listenner.alertEventPerform(alertType, buttonIndex, alertId);
      break;
    }
	}
	
	public void keyPressed(int keyCode) {
	  if (alertType == CUSTOM_UI_TYPE) {
      customeUI.doKeyPressed(keyCode);
      return;
    }
  }

  public void keyRepeated(int keyCode) {
    if (alertType == CUSTOM_UI_TYPE) {
      customeUI.doKeyRepeated(keyCode);
      return;
    }
  }
  
  public void mouseMoved(int x, int y) {
    if (alertType == CUSTOM_UI_TYPE) {
      customeUI.doMouseMoved(x, y);
      return;
    }
  }

  public void mousePressed(int x, int y) {
    if (alertType == CUSTOM_UI_TYPE) {
      customeUI.doMousePressed(x, y);
      return;
    }
  }

  public void mouseReleased(int x, int y) {
    if (alertType == CUSTOM_UI_TYPE) {
      customeUI.doMouseReleased(x, y);
      return;
    }
  }

  public void pointerDragged(int x, int y) {
    if (alertType == CUSTOM_UI_TYPE) {
      customeUI.doPointerDragged(x, y);
      return;
    }
  }

  public void pointerPressed(int x, int y) {
    if (alertType == CUSTOM_UI_TYPE) {
      customeUI.doPointerPressed(x, y);
      return;
    }
  }

  public void pointerReleased(int x, int y) {
    if (alertType == CUSTOM_UI_TYPE) {
      customeUI.doPointerReleased(x, y);
      return;
    }
  }

  public void destroy() {
    if ((alertType == CUSTOM_UI_TYPE) && (listenner != null)) {
      listenner.alertEventPerform(alertType, Alert.OK_BUTTON, alertId);
    }
    
    if (buttonSprites != null) {
      for (int i = 0; i < buttonSprites.length; i++) {
        if (buttonSprites[i] != null) {
          buttonSprites[i].detroy();
          buttonSprites[i] = null;
        }
      }
      buttonSprites = null;
    }
    
		removeTimerListener();
		if (customeUI != null) {
		  customeUI.isRunning = false;
		  customeUI = null;
		}
		alertTimeOut = Integer.MAX_VALUE;
		isRunning = false;
		parent = null;
		alertMessages.removeAllElements();
		buttonLabels = null;
	}
}
